import { Component, OnInit } from '@angular/core';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
import { NzNotificationService } from 'ng-zorro-antd';

@Component({
  selector: 'app-gentree',
  templateUrl: './gentree.component.html',
  styleUrls: ['./gentree.component.css']
})
export class GentreeComponent implements OnInit {

  generatedCode:string = '';
  paramForm:FormGroup;

  constructor(
    private fb:FormBuilder,
    private notificationService:NzNotificationService,
  ) { 
    this.initParamForm();
  }

  ngOnInit() {
  }

  // 初始化左边表单
  initParamForm(){
    this.paramForm = this.fb.group({
      textAttrName:['title',[Validators.required]],
      keyFieldName:['auto_key',[Validators.required]]
    });
  }

  msg(content:string){
    this.notificationService.blank('通知',content);
  }

  // 生成树形代码
  paramFormSubmit(){
    this.generatedCode = this.generateTreeCode();
  }

  generateTreeCode(){
    if( !this.paramForm.valid ){
      this.msg('表单验证未通过！');
      return;
    }

    let title = this.paramForm.value['textAttrName'];
    let key = this.paramForm.value['keyFieldName'];

    let ret = '';
    ret = ret + `
    // 组件内两个全局属性，递归时要用到
    levels = [];
    treeNodeKeyFieldName = '${key}';
    
    /**
     * 将二维数组转换为树形结构。类似数据库管理器左边的树形结构：数据库、表名、字段名，分3层的树形结构
     * 实际这里不限制层数，按照第二个参数中数组的长度动态分层，本案例以ng-zorro-antd 的 nzTree 为例制作
     * 如果更换为其他组件，那么修改方法 recursion 中的构建 node 的属性即可
     * 本代码必须结合自定义的数组工具类才可正常运行
     * @param rs 后端服务传递来的二维数组，在要分层的字段上会存在重复值
     * @param distFields 按照从上到下分层次的字段构成的字符串数组，例如：['schema_name','table_name','column_name']
     * @param keyFieldName 二维数组中主键字段名称，可唯一确定一行数据，一般是后端自动生成的自增主键
     */
    buildTree(rs:any[],distFields:string[],keyFieldName:string):any[]{
      let i = 0;
      for(i=0;i<distFields.length;i++){
        let ele = [this.buildDistArray(rs,distFields.slice(0,i+1)),distFields.slice(0,i+1)];
        this.levels.push(ele);
      }
  
      if( keyFieldName.length>0 ) this.treeNodeKeyFieldName = keyFieldName;
      return this.recursion(0,this.levels[0][0],this.levels[0][1]);
    }
  
    private recursion(level:number,curLevelArray:any[],distFields:string[]):any[]{
      let nodes = [];
      curLevelArray.forEach(ele => {
        let distField = distFields[distFields.length-1];
        let title = ele[distField];
        let node = {'${title}':title,'key':ele[this.treeNodeKeyFieldName],'children':[],'isLeaf':false};
        // 设置最后一层的节点都为叶子节点 - 逻辑叶子节点，未考虑事实叶子节点
        if( level===this.levels.length-1 ) node.isLeaf = true;
  
        let nextLevel = level + 1;
        let childrenNodes = [];
        if(nextLevel<this.levels.length){
          let subArray = this.getSames(this.levels[nextLevel][0],ele,this.levels[level][1]);
          childrenNodes = this.recursion(nextLevel,subArray,this.levels[nextLevel][1]);
        }
        node.children = childrenNodes;
        nodes.push(node);
      });
  
      return nodes;
    }
    `

    return ret;
  }

}
